package org.ysu.shoeShopping.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.ysu.shoeShopping.service.MinioFileService;
import org.ysu.shoeShopping.tools.Result;

import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@RestController
@RequestMapping(value = "/file", produces = MediaType.APPLICATION_JSON_VALUE)
@CrossOrigin(origins = "*")
@Slf4j
public class FileController {

    @Autowired
    private MinioFileService minioFileService;

    /**
     * 上传文件
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<String> uploadFile(@RequestParam("file") MultipartFile file) {
        System.out.println(file);
        try {
            if (file.isEmpty()) {
                return Result.fail("400", "文件不能为空");
            }

            // 验证文件大小 (10MB)
            if (file.getSize() > 10 * 1024 * 1024) {
                return Result.fail("400", "文件大小不能超过10MB");
            }

            // 验证文件类型
            String contentType = file.getContentType();
            if (contentType == null || !isValidFileType(contentType)) {
                return Result.fail("400", "不支持的文件类型，仅支持图片文件");
            }

            String fileUrl = minioFileService.uploadFile(file);
            log.info("文件上传成功: {}", fileUrl);

            return Result.success(fileUrl);
        } catch (Exception e) {
            log.error("文件上传失败", e);
            return Result.fail("500", "文件上传失败: " + e.getMessage());
        }
    }

    /**
     * 验证文件类型
     */
    private boolean isValidFileType(String contentType) {
        return contentType.startsWith("image/") &&
               (contentType.equals("image/jpeg") ||
                contentType.equals("image/png") ||
                contentType.equals("image/gif") ||
                contentType.equals("image/webp"));
    }

    /**
     * 获取文件访问URL
     */
    @GetMapping("/url/{fileName}")
    public Result<String> getFileUrl(@PathVariable String fileName) {
        try {
            if (!minioFileService.fileExists(fileName)) {
                return Result.fail("404", "文件不存在");
            }

            String fileUrl = minioFileService.getFileUrl(fileName);
            return Result.success(fileUrl);
        } catch (Exception e) {
            log.error("获取文件URL失败", e);
            return Result.fail("500", "获取文件URL失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件永久访问URL
     */
    @GetMapping("/public-url/{fileName}")
    public Result<String> getPublicFileUrl(@PathVariable String fileName) {
        try {
            if (!minioFileService.fileExists(fileName)) {
                return Result.fail("404", "文件不存在");
            }

            String publicUrl = minioFileService.getPublicFileUrl(fileName);
            return Result.success(publicUrl);
        } catch (Exception e) {
            log.error("获取文件公开URL失败", e);
            return Result.fail("500", "获取文件公开URL失败: " + e.getMessage());
        }
    }

    /**
     * 下载文件
     */
    @GetMapping("/download/{fileName}")
    public ResponseEntity<InputStreamResource> downloadFile(@PathVariable String fileName) {
        try {
            if (!minioFileService.fileExists(fileName)) {
                return ResponseEntity.notFound().build();
            }

            InputStream inputStream = minioFileService.getFileStream(fileName);
            InputStreamResource resource = new InputStreamResource(inputStream);

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\"");
            headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
            headers.add(HttpHeaders.PRAGMA, "no-cache");
            headers.add(HttpHeaders.EXPIRES, "0");

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);

        } catch (Exception e) {
            log.error("文件下载失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 删除文件
     */
    @DeleteMapping("/delete/{fileName}")
    public Result<String> deleteFile(@PathVariable String fileName) {
        try {
            if (!minioFileService.fileExists(fileName)) {
                return Result.fail("404", "文件不存在");
            }

            minioFileService.deleteFile(fileName);
            return Result.success("文件删除成功");
        } catch (Exception e) {
            log.error("文件删除失败", e);
            return Result.fail("500", "文件删除失败: " + e.getMessage());
        }
    }

    /**
     * 检查文件是否存在
     */
    @GetMapping("/exists/{fileName}")
    public Result<Boolean> fileExists(@PathVariable String fileName) {
        try {
            boolean exists = minioFileService.fileExists(fileName);
            return Result.success(exists);
        } catch (Exception e) {
            log.error("检查文件存在性失败", e);
            return Result.fail("500", "检查文件存在性失败: " + e.getMessage());
        }
    }
}